package cn.wonderland.resthome.service.impl;

import cn.wonderland.basic.util.BussinessException;
import cn.wonderland.resthome.domain.Bed;
import cn.wonderland.resthome.domain.Nurse;
import cn.wonderland.resthome.domain.Oldman;
import cn.wonderland.resthome.mapper.BedMapper;
import cn.wonderland.resthome.mapper.NurseMapper;
import cn.wonderland.resthome.mapper.OldmanMapper;
import cn.wonderland.resthome.service.IOldmanService;
import cn.wonderland.basic.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wonderland
 * @since 2023-05-01
 */
@Service
@Slf4j
public class OldmanServiceImpl extends BaseServiceImpl<Oldman> implements IOldmanService {

    @Autowired
    private OldmanMapper oldmanMapper;

    @Autowired
    private BedMapper bedMapper;

    @Autowired
    private NurseMapper nurseMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void add(Oldman oldman) {
        // 查询未使用状态的床位
       List<Bed> bedList = bedMapper.forOldMan();
        if (bedList.size() > 0) { // 大于0表示还有空余床位
            // 添加老人到数据库，并关联床位和护工
            // 检查床位是否已被占用
            Bed bed = bedMapper.findById(oldman.getBedId());
            if (bed.getBedState() == 28) {
                throw new BussinessException("该床位已被占用，请选择其他床位！");
            }
            // 检查护工是否已经管理了2个老人
            Nurse byId = nurseMapper.findById(oldman.getNurseId());
            if (byId.getOldmanCount() >= 2) {
                throw new BussinessException("该护工管理的老人已达到上限，请选择其他护工！");
            }
            // 护工管理人数+1
            Nurse nurse = new Nurse();
            nurse.setId(oldman.getNurseId());
            nurse.setOldmanCount(byId.getOldmanCount() + 1);
            nurseMapper.update(nurse);
            // 修改床位状态为已使用
            bed.setId(oldman.getBedId());
            bed.setBedState(28);
            bedMapper.update(bed);
            // 保存老人到数据库
            oldman.setState(33);
            oldman.setCreateTime(new Date());
            oldmanMapper.add(oldman);
            log.info("add===老人到数据库");
        } else {
            // 床位已满，将老人信息存入 Redis 队列中
            redisTemplate.opsForList().leftPush("oldmanQueue", oldman);
            throw new BussinessException("床位已满，自动排队中。。。");
        }
    }

    /**
     * 定时任务方法
     */
    @Scheduled(fixedDelay = 10000) // 每隔 10 秒执行一次任务
    public void processOldmanQueue() {
        Oldman oldman = (Oldman) redisTemplate.opsForList().rightPop("oldmanQueue");
        if (oldman != null) {
            List<Bed> bedList = bedMapper.forOldMan();
            if (bedList.size() > 0) {
                // 添加老人到数据库，并关联床位和护工
                add(oldman);
                log.info("添加老人到数据库");
            } else {
                // 床位仍然已满，将老人信息放回队列的头部，等待下一次执行任务时处理
                redisTemplate.opsForList().leftPush("oldmanQueue", oldman);
                log.info("床位仍然已满，继续排队等待！");
            }
        }
    }

    /***
     * 修改时，应该检查：
     * 修改后的床位是否已经被占用
     * 修改后的护工是否已经管理了2个老人
     * 如果有-->抛出异常
     * 如果没有-->修改信息 并且将之前的床位状态修改，之前的护工管理人数-1
     *
     * @param oldman
     */
    @Override
    public void update(Oldman oldman) {
        // 检查床位是否已被占用
        Bed bed = bedMapper.findById(oldman.getBedId());
        if (bed.getBedState() == 28 && !oldman.getBedId().equals(oldman.getBed().getId())) {
            throw new BussinessException("该床位已被占用，请选择其他床位！");
        }
        // 检查护工是否已经管理了2个老人
        Nurse byId = nurseMapper.findById(oldman.getNurseId());
        if (byId.getOldmanCount() >= 2  && !oldman.getNurseId().equals(oldman.getNurse().getId())) {
            throw new BussinessException("该护工管理的老人已达到上限，请选择其他护工！");
        }
        // 修改之前的床位和护工信息
        Bed oldBed = bedMapper.findById(oldman.getBed().getId());
        if (oldBed != null){
            oldBed.setId(oldman.getBed().getId());
            oldBed.setBedState(29); // 29 = 未使用状态
            bedMapper.update(oldBed);
        }
        Nurse oldNurse = nurseMapper.findById(oldman.getNurse().getId());
        if (oldNurse != null){
            oldNurse.setId(oldman.getNurse().getId());
            oldNurse.setOldmanCount(oldNurse.getOldmanCount() - 1);
            nurseMapper.update(oldNurse);
        }
        // 新护工管理人数+1
        Nurse nurse = new Nurse();
        nurse.setId(oldman.getNurseId());
        nurse.setOldmanCount(byId.getOldmanCount() + 1);
        nurseMapper.update(nurse);
        // 修改新床位状态为已使用
        bed.setId(oldman.getBedId());
        bed.setBedState(28);
        bedMapper.update(bed);
        // 修改老人数据到数据库
        oldmanMapper.update(oldman);
    }

    @Override
    public void delete(Long id) {
        // 获取老人信息
        Oldman oldman = oldmanMapper.findById(id);
        if (oldman == null) {
            throw new BussinessException("老人不存在！");
        }
        // 清空床位和护工的关联关系
        Bed bed = bedMapper.findById(oldman.getBedId());
        if (bed != null){
            bed.setId(oldman.getBedId());
            bed.setBedState(29); // 29 = 未使用状态
            bedMapper.update(bed);
        }
        Nurse nurse = nurseMapper.findById(oldman.getNurseId());
        if (nurse != null){
            nurse.setId(oldman.getNurseId());
            nurse.setOldmanCount(nurse.getOldmanCount() - 1);
            nurseMapper.update(nurse);
        }
        // 删除老人信息
        oldmanMapper.delete(id);
    }
}
